package com.ay.weixin.autoreply.event.handle;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;

import org.lizar.config.keys.Keys;
import org.lizar.controller.loader.EventLoader;
import org.lizar.ioc.Cell;
import org.lizar.ioc.Container;
import org.lizar.json.JObject;
import org.lizar.json.util.JSONParser;
import org.lizar.log.Log;
import org.lizar.log.Logger;
import org.lizar.util.StringHelper;
import org.lizar.util.https.Https;

import com.ay.weixin.autoreply.domain.AccessTokenModule;
import com.ay.weixin.fdc.boss.user.db.WeiXinInfoDao;
import com.ay.weixin.fdc.boss.user.domain.UserWeiXinInfo;
import com.ximpleware.AutoPilot;
import com.ximpleware.VTDGen;
import com.ximpleware.VTDNav;
import com.ximpleware.XPathParseException;

public class HandleInput implements Cell {

	Log log =Logger.newInstance(this.getClass());
	
	private HandleMsg handle_msg;
	
	private HandleEvent handle_event;
	
	private static AccessTokenModule access_token;
	
	private static WeiXinInfoDao weixin_info_dao;

	
	@Override
	public void init_property() throws Exception {
		
		handle_msg=Container.get(HandleMsg.class);
		handle_event=Container.get(HandleEvent.class);
		access_token=Container.get(AccessTokenModule.class);
		weixin_info_dao=Container.get(WeiXinInfoDao.class);
		
		
	}

	
	public void handle_input(EventLoader el,String echogetStr,long wxproject_id) throws IOException{
		
		String result=getBody(el);
		if(StringHelper.isNull(result)||!result.startsWith("<xml>")||!result.endsWith("</xml>")){
			log.error("System may get expression error as msg is not correct:");
			el.text(echogetStr);
			return;
		}
		
		VTDGen vg = new VTDGen();
        vg.setDoc(result.getBytes());
        try {
			vg.parse(false);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("System may get expression error ",e);
			el.text(echogetStr);
			return;
		}
        
        VTDNav vn = vg.getNav();
        AutoPilot ap = new AutoPilot(vn);
        JObject msg=getMessage(vn,ap);
        if(msg==null){
        	log.error("System may get expression error as express msg is null:"+result);
        	el.text(echogetStr);
			return;
        }
        
        if(StringHelper.equals(msg.getStr("event"),"TEMPLATESENDJOBFINISH")){
        	el.text("notified,thanks!");
        	return;
        }
        
        System.out.println("body:"+result);
        fetch_user_info( wxproject_id,msg.getStr("from_user_name"), msg.getStr("event"));
       
        //text/image/voice/video/location/link/event
        if(StringHelper.equals(msg.getStr("msg_type"), "event")){
        	handle_event.handle_event(msg,el,echogetStr,wxproject_id);
        }else{
        	handle_msg.handle_msg(msg,el,echogetStr,wxproject_id);
        }
		
	} 
	
	public static  void fetch_user_info(long wxproject_id,String ropenid,String event) throws UnsupportedEncodingException{
		if(StringHelper.equals("input",Keys.getStr("input_message.pick_user_info"))||
				(StringHelper.equals("subscribe",Keys.getStr("input_message.pick_user_info"))&&
						StringHelper.equals(Keys.get("input_message_event_type.subscribe"),event)
						)){
			
			UserWeiXinInfo info=null;
			
			try {
				info=weixin_info_dao.get(ropenid);
			} catch (SQLException e) {
				e.printStackTrace();
				return;
			}
			String result=null;
			try {
				result=Https.GetMethod(String.format(Keys.getStr("weixin_url.get_user_info"), access_token.getAccessToken( wxproject_id),ropenid));
			} catch (Exception e) {
				e.printStackTrace();
				return;
			}
			if(StringHelper.isNull(result)){
				return;
			}
			JObject user_info=(JObject)JSONParser.parse(result);
			if(user_info==null){
				System.out.println("user info is null:"+user_info);
				return;
			}
			if(info==null){
				info=new UserWeiXinInfo();
				info.setCity(user_info.getStr("city"));
				info.setCountry(user_info.getStr("country"));
				info.setNickname(user_info.getStr("nickname").trim());
				info.setProvince(user_info.getStr("province"));
				info.setId(ropenid);
				info.setSex(user_info.getInt("sex")+"");
				info.setSubscribe(user_info.getInt("subscribe"));
				System.out.println("insert "+"name:\""+info.getNickname().trim()+"\"");
				try {
					weixin_info_dao.insert(info);
				} catch (SQLException e) {
					e.printStackTrace();
					return;
				}
			}else{
				info.setCity(user_info.getStr("city"));
				info.setCountry(user_info.getStr("country"));
				info.setNickname(user_info.getStr("nickname").trim());
				info.setProvince(user_info.getStr("province"));
				info.setSex(user_info.getInt("sex")+"");
				info.setSubscribe(user_info.getInt("subscribe"));
				System.out.println("update "+"name:\""+info.getNickname().trim()+"\"");
				try {
					weixin_info_dao.update(info);
				} catch (SQLException e) {
					e.printStackTrace();
					return;
				}
			}
			
		}
	}

	
	public enum MessageXpath{
		to_user_name("/xml/ToUserName/text()", "公众平台账号"),
		from_user_name("/xml/FromUserName/text()", "发送方帐号"),
		format("/xml/Format/text()", "语音格式，如amr，speex等"),
		create_time("/xml/CreateTime/text()", "消息创建时间"),
		msg_type("/xml/MsgType/text()", "消息类型text/image/voice/video/location/link/event"),
		content("/xml/Content/text()", "文本消息内容"),
		msg_id("/xml/MsgId/text()", "消息id"),
		pic_url("/xml/PicUrl/text()", "图片链接"),
		media_id("/xml/MediaId/text()", "视频消息媒体id，可以调用多媒体文件下载接口拉取数据。"),
		thunb_media_id("/xml/ThumbMediaId/text()","视频消息缩略图的媒体id，可以调用多媒体文件下载接口拉取数据。"),
		location_x("/xml/Location_X/text()", "地理位置维度"),
		location_y("/xml/Location_Y/text()", "地理位置经度"),
		scale("/xml/Scale/text()", "地图缩放大小"),
		label("/xml/Label/text()", "地理位置信息"),
		title("/xml/Title/text()", "消息标题"),
		description("/xml/Description/text()", "消息描述"),
		url("/xml/Url/text()", "消息链接"),
		precision("/xml/Precision/text()", "地理位置精度"),
		longitude("/xml/Longitude/text()", "地理位置经度"),
		latitude("/xml/Latitude/text()", "地理位置纬度"),
		ticket("/xml/Ticket/text()", "二维码的ticket，可用来换取二维码图片"),
		event("/xml/Event/text()", "事件类型，subscribe"),
		event_key("/xml/EventKey/text()", "事件KEY值，qrscene_为前缀，后面为二维码的参数值")
		;
		private String xpath;
		private String desc;
		private MessageXpath(String xpath,String desc){
			this.xpath=xpath;
			this.desc=desc;
		}
		
		public static MessageXpath[] xpaths=values();
	}
	
	/**
	 * 
	 * 通过Group组中的input_message_xpath，获得所有的消息数据，存入JSON对象中
	 * 
	 * */
	private JObject getMessage( VTDNav vn,AutoPilot ap){
		
		JObject msg=new JObject();
		for(MessageXpath xpath:MessageXpath.xpaths){
			try {
				ap.selectXPath(xpath.xpath);
			} catch (XPathParseException e) {
				e.printStackTrace();
				log.error("System handling input message failure :"+xpath.xpath,e);
				continue;
			}
			try {
				ap.evalXPath();
				msg.put(xpath.name(), vn.toString(vn.getCurrentIndex()));
			} catch (Exception e) {
				log.error("System handling input message failure :"+xpath.xpath,e);
				continue;
			}
		}
		
		return msg;
	}
	
	

	
	private String getBody(EventLoader el) throws IOException{
		 BufferedReader sis= el.request().getReader();
		 char[] buf = new char[1024];
		 int len = 0;
		 StringBuffer sb = new StringBuffer();
		 while((len = sis.read(buf))!= -1){
		  sb.append(buf,0,len);
		 }
		 return sb.toString();
	}
}
